package org.jeecg.util;


import org.apache.commons.codec.binary.Base64;
import org.apache.commons.lang3.ArrayUtils;
import org.springframework.util.StringUtils;

import javax.crypto.*;
import javax.crypto.spec.SecretKeySpec;
import java.io.UnsupportedEncodingException;
import java.nio.charset.StandardCharsets;
import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;


public class AESUtil {

    private static final String AES_ALGORITHM = "AES";

    private static final String UTF8 = StandardCharsets.UTF_8.name();


    /* AES解密 String*/
    public static String decryptStrAES(String text, String key){
        if(!StringUtils.hasLength(text)){
            System.out.println("");
            //ExcpUtils.throwExp("decode text should not be null or empty.");
        }
        byte[] decodeBytes = decryptByteAES(Base64.decodeBase64(text.getBytes(StandardCharsets.UTF_8)), key);
        return new String(decodeBytes, StandardCharsets.UTF_8);
    }


    public static byte[] decryptByteAES(byte[] encryptedBytes, String key){
        if(ArrayUtils.isEmpty(encryptedBytes)){
            //ExcpUtils.throwExp("decode encryptedBytes should not be empty.");
        }
        if(!StringUtils.hasLength(key)){
            //ExcpUtils.throwExp("key :" + key + ", decode key should not be null or empty.");
        }
        Cipher cipher = getAESCipher(key, Cipher.DECRYPT_MODE);
        byte[] decodeBytes = null;
        try {
            decodeBytes = cipher.doFinal(encryptedBytes);
        } catch (IllegalBlockSizeException | BadPaddingException e) {
            //ExcpUtils.throwExp(e.getClass().getName()+": decode byte fail. "+e.getMessage());
        }
        return decodeBytes;
    }

    public static Cipher getAESCipher(String key, int mode){
        if(!StringUtils.hasLength(key)){
            //ExcpUtils.throwExp("key :" + key + ", should not be null or empty.");
        }
        Cipher cipher = null;
        SecretKey secretKey;
        try {
            cipher = Cipher.getInstance(AES_ALGORITHM);
            byte[] keyBytes = key.getBytes(UTF8);
            secretKey = new SecretKeySpec(keyBytes, AES_ALGORITHM);
            cipher.init(mode, secretKey);
        } catch (NoSuchAlgorithmException | NoSuchPaddingException e) {
            //ExcpUtils.throwExp(e.getClass().getName()+": get cipher instance wrong. "+e.getMessage());
        } catch (UnsupportedEncodingException u){
            //ExcpUtils.throwExp(u.getClass().getName()+": key transfer bytes fail. "+u.getMessage());
        } catch (InvalidKeyException i) {
            //ExcpUtils.throwExp(i.getClass().getName()+": key is invalid. "+i.getMessage());
        }
        return cipher;
    }






    /* AES加密 String */
    public static String encryptStrAES(String text, String key){
        if(!StringUtils.hasLength(text)){
            //ExcpUtils.throwExp("encode text should not be null or empty.");
        }
        byte[] encodeBytes = encryptByteAES(text.getBytes(StandardCharsets.UTF_8), key);
        return Base64.encodeBase64String(encodeBytes);
    }
    /* AES加密 originalBytes */
    public static byte[] encryptByteAES(byte[] originalBytes, String key){
        if(ArrayUtils.isEmpty(originalBytes)){
            //ExcpUtils.throwExp("encode originalBytes should not be empty.");
        }
        if(!StringUtils.hasLength(key)){
            //ExcpUtils.throwExp("key :" + key + ", encode key should not be null or empty.");
        }
        Cipher cipher = getAESCipher(key, Cipher.ENCRYPT_MODE);
        byte[] encodeBytes = null;
        try {
            encodeBytes = cipher.doFinal(originalBytes);
        } catch (IllegalBlockSizeException | BadPaddingException e) {
            //ExcpUtils.throwExp(e.getClass().getName()+": encode byte fail. "+e.getMessage());
        }
        return encodeBytes;
    }




}
